# 导入用于处理图像的PIL库中的Image模块
from PIL import Image
# 导入用于创建图形用户界面的tkinter库
import tkinter as tk
# 从tkinter库中导入文件对话框模块，用于让用户选择文件和保存文件
from tkinter import filedialog

# 定义一个函数，用于压缩图片
def compress_image(input_path, output_path, quality=80):
    # 尝试执行以下代码块
    try:
        # 使用with语句打开指定路径的图片文件，确保文件在使用完后正确关闭
        with Image.open(input_path) as img:
            # 将打开的图片以指定的质量保存到输出路径，同时进行优化
            img.save(output_path, optimize=True, quality=quality)
        # 打印图片成功压缩并保存的信息
        print(f"图片 {input_path} 已成功压缩并保存到 {output_path}")
    # 若输入的图片文件未找到，捕获FileNotFoundError异常
    except FileNotFoundError:
        # 打印输入图片未找到的错误信息
        print(f"输入图片 {input_path} 未找到。")
    # 若出现其他异常，捕获并打印异常信息
    except Exception as e:
        # 打印压缩图片时出现的错误信息
        print(f"压缩图片时出现错误: {e}")

# 定义一个函数，用于让用户选择输入的图片文件
def select_input_image():
    # 声明input_image_path为全局变量，以便在函数内部修改它的值
    global input_image_path
    # 弹出文件选择对话框，让用户选择图片文件（支持PNG、JPG、JPEG格式）
    input_image_path = filedialog.askopenfilename(filetypes=[("图片文件", "*.png;*.jpg;*.jpeg")])
    # 更新显示输入图片路径的标签文本
    input_label.config(text=f"选择的输入图片: {input_image_path}")

# 定义一个函数，用于让用户选择输出的图片文件保存路径
def select_output_image():
    # 声明output_image_path为全局变量，以便在函数内部修改它的值
    global output_image_path
    # 弹出文件保存对话框，默认文件扩展名为.jpg，只允许保存为JPEG格式
    output_image_path = filedialog.asksaveasfilename(defaultextension=".jpg", filetypes=[("JPEG 文件", "*.jpg")])
    # 更新显示输出图片路径的标签文本
    output_label.config(text=f"选择的输出图片: {output_image_path}")

# 定义一个函数，用于执行图片压缩操作
def perform_compression():
    # 检查输入图片路径和输出图片路径是否都已被设置
    if input_image_path and output_image_path:
        # 调用compress_image函数进行图片压缩
        compress_image(input_image_path, output_image_path)
    else:
        # 若输入或输出路径未设置，打印提示信息
        print("请先选择输入图片和输出图片路径。")

# 创建一个主窗口实例
root = tk.Tk()
# 设置主窗口的大小为400x300像素
root.geometry("400x300")
# 设置主窗口的标题
root.title("图片压缩工具")

# 初始化全局变量input_image_path，用于存储用户选择的输入图片路径
input_image_path = ""
# 初始化全局变量output_image_path，用于存储用户选择的输出图片路径
output_image_path = ""

# 创建一个按钮，文本为“选择输入图片”，点击时调用select_input_image函数
input_button = tk.Button(root, text="选择输入图片", command=select_input_image)
# 将按钮放置在主窗口中，垂直方向上留出10个像素的间距
input_button.pack(pady=10)

# 创建一个标签，用于显示用户选择的输入图片路径，初始文本为“选择的输入图片: 无”
input_label = tk.Label(root, text="选择的输入图片: 无")
# 将标签放置在主窗口中，垂直方向上留出5个像素的间距
input_label.pack(pady=5)

# 创建一个按钮，文本为“选择输出图片路径”，点击时调用select_output_image函数
output_button = tk.Button(root, text="选择输出图片路径", command=select_output_image)
# 将按钮放置在主窗口中，垂直方向上留出10个像素的间距
output_button.pack(pady=10)

# 创建一个标签，用于显示用户选择的输出图片路径，初始文本为“选择的输出图片: 无”
output_label = tk.Label(root, text="选择的输出图片: 无")
# 将标签放置在主窗口中，垂直方向上留出5个像素的间距
output_label.pack(pady=5)

# 创建一个按钮，文本为“开始压缩”，点击时调用perform_compression函数
compress_button = tk.Button(root, text="开始压缩", command=perform_compression)
# 将按钮放置在主窗口中，垂直方向上留出20个像素的间距
compress_button.pack(pady=20)

# 进入主事件循环，使窗口保持显示并响应用户操作
root.mainloop()